package LoginManager;

import Utils.WEBRootUrl;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServlet;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.util.*;
import java.util.List;

public class ImagePreProcess2 {
    //8邻降噪
    public static BufferedImage denoise(BufferedImage image) throws Exception{
        final int NUM = 6;
        int width = image.getWidth();
        int height = image.getHeight();
        for (int x = 1; x < width; x++) {
            for (int y = 1; y < height; y++) {//行反列
                if (image.getRGB(x, y) == Color.BLACK.getRGB()) {
                    int nCount = 0;
                    for (int m = x - 1; m <= x + 1; m++) {
                        for (int n = y - 1; n <= y + 1; n++) {
                            if (image.getRGB(m, n) == Color.WHITE.getRGB()) {
                                nCount++;
                            }
                        }
                    }
                    if (nCount >= NUM) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
        }
        ImageIO.write(image, "gif", new File("C:\\Users\\Administrator\\Desktop\\CodeTest\\" +  "02.gif"));
        return image;

    }

    public static boolean replaceByWhite(int colorInt) {
        Color color = new Color(colorInt);
        if (color.getBlue() > 210) {
            return true;
        }
        return false;
    }

    //阈值处理
    public static BufferedImage removeBackGround(BufferedImage image) throws Exception {
        int width = image.getWidth();
        int height = image.getHeight();
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                if (replaceByWhite(image.getRGB(x, y)) == true) {
                    image.setRGB(x, y, Color.WHITE.getRGB());
                } else {
                    image.setRGB(x, y, Color.BLACK.getRGB());
                }
            }
        }
        //去除边界
        for(int i=0;i<height;i++){
            image.setRGB(0, i, Color.WHITE.getRGB());
            image.setRGB(width-1, i, Color.WHITE.getRGB());
        }

        for(int i=0;i<width;i++){
            image.setRGB(i, 0, Color.WHITE.getRGB());
            image.setRGB(i,height-1, Color.WHITE.getRGB());
        }

        ImageIO.write(image, "gif", new File("C:\\Users\\Administrator\\Desktop\\CodeTest\\" +  "01.gif"));
        return image;
    }


    //切割算法(待优化)
    public static List<BufferedImage> splitImage(BufferedImage img)
            throws Exception {
        List<BufferedImage> subImgs = new ArrayList<BufferedImage>();
        subImgs.add(img.getSubimage(0, 0, 16, 21));
        subImgs.add(img.getSubimage(17, 0, 11, 21));
        subImgs.add(img.getSubimage(28, 0, 13, 21));
        subImgs.add(img.getSubimage(40, 0, 18, 21));
        return subImgs;
    }

    //加载训练库
    public static Map<BufferedImage, String> loadTrainData() throws Exception {
        Map<BufferedImage, String> map = new HashMap<BufferedImage, String>();
        System.out.println(WEBRootUrl.getRootUrl() + "trainData");
        File dir = new File(WEBRootUrl.getRootUrl() + "trainData");
        File[] files = dir.listFiles();
        for (File file : files) {
            InputStream in = new FileInputStream(file);
            map.put(ImageIO.read(in), file.getName().charAt(0) + "");
        }
        return map;
    }

    //类knn算法识别字符(待优化)
    public static String getSingleCharOcr(BufferedImage img,
                                          Map<BufferedImage, String> map) {
        String result = "";
        int width = img.getWidth();
        int height = img.getHeight();
        int min = width * height;

        for (BufferedImage bi : map.keySet()) {
            int minWidth = Math.min(bi.getWidth(),width);
            int minHeight = Math.min(bi.getHeight(),height);
            int count = 0;
            Label1: for (int x = 0; x < minWidth; ++x) {
                for (int y = 0; y < minHeight; ++y) {
                    if (img.getRGB(x, y) != bi.getRGB(x, y)) {
                        count++;
                        if (count >= min)
                            break Label1;
                    }
                }
            }
            if (count < min) {
                min = count;
                result = map.get(bi);
            }
        }
        return result;
    }


    public static String getCodeString(BufferedImage bufferedImage) throws Exception{
        StringBuffer results = new StringBuffer();

        //预处理
        bufferedImage = removeBackGround(bufferedImage);
        bufferedImage = denoise(bufferedImage);
        //分割验证码
        List<BufferedImage> splitImage = splitImage(bufferedImage);
        //读取识别库
        Map<BufferedImage, String> maps = loadTrainData();
        int num=0;
        for (BufferedImage img : splitImage) {
            results.append(getSingleCharOcr(img,maps));
            ImageIO.write(img, "gif", new File("C:\\Users\\Administrator\\Desktop\\CodeTest\\" + num++ + "Slice.gif"));
        }
        return results.toString();
    }

    public static String getCodeString(String imgUrl) throws Exception{
        File file = new File(imgUrl);
        BufferedImage bufferedImage1 = ImageIO.read(file);
        return getCodeString(bufferedImage1);
    }

}
